#ifndef XSTRING_H_
#define XSTRING_H_
#include <string>
#include <cstring>
#include <iostream>
#include <cassert>

char* safeStrdup(const char* s);
char* safeStrndup(const char* s,std::size_t len);


class CharSequence
    {
    public:
	typedef std::size_t size_type;
	static const size_type	npos = static_cast<size_type>(-1);
	CharSequence();
	virtual ~CharSequence();
	virtual size_type size() const=0;
	virtual char at(size_type idx) const=0;
	char operator[](size_type idx) const;
	virtual void print(std::ostream& out) const;
	bool equals(const CharSequence* cp) const;
	bool equalsIgnoreCase(const CharSequence* cp) const;
	int compareTo(const CharSequence* cp) const;
	size_type find(const CharSequence* other,size_type beg=0) const;
	bool startsWith(const CharSequence* cp) const;
	bool endsWith(const CharSequence* cp) const;
	std::string toString() const;
    };

std::ostream& operator<<(std::ostream& os, const CharSequence* seq);

class DelegateCharSequence:public CharSequence
    {
    protected:
	DelegateCharSequence();
    public:
	virtual ~DelegateCharSequence();
	virtual const CharSequence* delegate() const =0;
	virtual size_type size() const;
	virtual char at(size_type idx) const;
   };

class SubStringSequence:public CharSequence
    {
    protected:
	const CharSequence* _delegate;
    private:
	size_type _pos;
	size_type _len;
    public:
	SubStringSequence(const CharSequence* delegate,size_type pos,size_type len);
	SubStringSequence(const CharSequence* delegate);
	virtual ~SubStringSequence();
	virtual size_type size() const;
	virtual char at(size_type idx) const;
   };

class AbstractCString:public CharSequence
    {
    protected:
	size_t _len;
	AbstractCString(size_t len);
    public:
	virtual ~AbstractCString();
	virtual const char* data() const=0;
	virtual size_type size() const;
	virtual char at(size_type idx) const=0;
	virtual void print(std::ostream& out) const;
    };


class CStringWapper:public AbstractCString
    {
    private:
	const char* _s;
    public:
	CStringWapper(const char* s,size_t len);
	CStringWapper(const char* s);
	virtual ~CStringWapper();
	virtual const char* data() const;
	virtual char at(size_type idx) const;
    };

class CStringCopy:public AbstractCString
    {
    private:
	char* _s;
    public:
	CStringCopy(const char* s,size_t len);
	CStringCopy(const char* s);
	CStringCopy(const CStringCopy& cp);
	CStringCopy(const CharSequence* cp);
	virtual ~CStringCopy();
	CStringCopy& operator=(const CStringCopy& cp);
	virtual const char* c_str() const;
	virtual const char* data() const;
	virtual char at(size_type idx) const;
    };

class ConcatCharSequence:public CharSequence
    {
    private:
	CharSequence** _delegates;
	std::size_t _nseqs;
	size_type length;
    public:
	ConcatCharSequence(const CharSequence** seqs,size_t nseq);
	virtual ~ConcatCharSequence();
	virtual size_type size() const;
	virtual char at(size_type idx) const;
    };


#endif

